﻿

namespace LxCore
{
    public partial class IterationStepSet : JsObject
    {
        public IterationStepSet()
        {
            MaxStepRule = new MaxStepStopRule(this);
        }
        public int CurrentStep = 0;
        public bool CurrentStepOngoing = false;

        private MaxStepStopRule _MaxStepRule;
        public MaxStepStopRule MaxStepRule
        {
            get { return _MaxStepRule; }
            set
            {
                _MaxStepRule = value;
                RaisePropertyChanged(nameof(MaxStepRule));
            }
        }
        protected BoolCollector StopBoolCollector = new();
        public void AddStopBool(StopRuleBase rule)
        {
            StopBoolCollector.AddRule(rule.IsLogicOr, rule.IsStop());
        }
        public void AddStopBool(bool isLogicOr, bool isStop)
        {
            StopBoolCollector.AddRule(isLogicOr, isStop);
        }

        public virtual void StepStart()//迭代步先执行start，
        {
            CurrentStepOngoing = true;
            CurrentStep++;
            LxSim.Sim.Steps.CurrentTotalStep++;
            StopBoolCollector = new BoolCollector();
        }
        public virtual void StepEnd()
        {
            if (MaxStepRule != null)
            {
                AddStopBool(MaxStepRule);
            }
            CurrentStepOngoing = false;
        }
        public bool IsContinue()
        {
            return !IsStop();
        }
        public virtual bool IsStop()
        {
            return StopBoolCollector.GetIsStop();
        }
        public override void FromJsonKV(string key, IJsonReader jsReader)
        {
            switch (key)
            {
                case nameof(CurrentStep): CurrentStep = jsReader.ReadInt(); break;
                case nameof(MaxStepRule): jsReader.ReadObject(MaxStepRule, e => MaxStepRule = e, t => new MaxStepStopRule(this)); break;
                default: base.FromJsonKV(key, jsReader); break;
            }
        }
        public override void ToJsonKV(IJsonWriter jsWriter)
        {
            base.ToJsonKV(jsWriter);
            jsWriter.WriteInt(nameof(CurrentStep), CurrentStep);
            jsWriter.WriteObject(nameof(MaxStepRule), MaxStepRule);
        }
        public struct BoolCollector
        {
            public BoolCollector() { }
            private bool Or = false;
            private bool And = true;
            private bool IsAndUsed = false;
            public void AddRule(bool isLogicOr, bool newBool)
            {
                if (isLogicOr)
                {
                    Or = Or || newBool;
                }
                else
                {
                    IsAndUsed = true;
                    And = And && newBool;
                }
            }
            public bool GetIsStop()
            {
                return IsAndUsed ? (Or || And) : Or;
            }
        }
        public class MaxStepStopRule : StopRuleBase
        {
            public MaxStepStopRule(IterationStepSet step)
            {
                this.Parent = step;
                IsLogicOr = true;
            }
            private IterationStepSet Step => Parent as IterationStepSet;

            private int _MaxStep = 2;
            public int MaxStep
            {
                get { return _MaxStep; }
                set { _MaxStep = value; RaisePropertyChanged(nameof(MaxStep)); }
            }

            public override bool IsStop()
            {
                return Step.CurrentStep >= MaxStep;
            }
            public override void FromJsonKV(string key, IJsonReader jsReader)
            {
                switch (key)
                {
                    case nameof(MaxStep):MaxStep = jsReader.ReadInt();break;
                    default: base.FromJsonKV(key, jsReader); break;
                }
            }
            public override void ToJsonKV(IJsonWriter jsWriter)
            {
                base.ToJsonKV(jsWriter);
                jsWriter.WriteInt(nameof(MaxStep), MaxStep);
            }
        }
    }
}
